package com.enzoism.springboot.dive.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.Days;
import org.joda.time.LocalDateTime;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 时间工具类
 * 借助joda工具类
 */
@Slf4j
public class DateUtil {
    private DateUtil() {
        throw new IllegalStateException("不支持对象初始化");
    }

    /**
     * 将时间字符转化为时间
     * 可以转化YYYY_MM_DD和YYYY_MM_DD_HH_MM_SS的时间字符
     */
    public static Date getDateByDateStr(String dateStr) {
        String format = StringUtils.length(dateStr) == StringUtils.length(DateConstants.YYYY_MM_DD) ? DateConstants.YYYY_MM_DD : DateConstants.YYYY_MM_DD_HH_MM_SS;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        try {
            return simpleDateFormat.parse(dateStr);
        } catch (ParseException e) {
            String errMsg = String.format("时间格式化失败,[date=%s]不合法", dateStr);
            log.error(errMsg);
            // TODO 改为自己项目的自定义异常
            throw new RuntimeException(errMsg);
        }
    }


    /**
     * 将YYYY_MM_DD 转化为 将YYYY_MM_DD_HH_MM_SS
     */
    public static String getStartFullTimeofDateStr(String dataStr) {
        Date dateByString = getDateByDateStr(dataStr);
        LocalDateTime startLocalTimeByDate = getStartLocalTimeByDate(dateByString);
        String fullDateTimeStr = new LocalDateTime(startLocalTimeByDate).
                toString(DateConstants.YYYY_MM_DD_HH_MM_SS);
        log.info("转化后的全量时间：" + fullDateTimeStr);
        return fullDateTimeStr;
    }

    /**
     * 获取今天的开始的全量时间 YYYY_MM_DD_HH_MM_SS
     */
    public static String getStartFullTimeOfToday() {
        String fullDateTimeStr = new LocalDateTime().
                hourOfDay().withMaximumValue().
                minuteOfHour().withMinimumValue().
                secondOfMinute().withMinimumValue().
                millisOfSecond().withMinimumValue().
                toString(DateConstants.YYYY_MM_DD_HH_MM_SS);
        log.info("今天最早的开始时间：" + fullDateTimeStr);
        return fullDateTimeStr;
    }

    /**
     * 获取今天的结束的全量时间 YYYY_MM_DD_HH_MM_SS
     */
    public static String getEndFullTimeOfToday() {
        String fullDateTimeStr = new LocalDateTime().
                hourOfDay().withMaximumValue().
                minuteOfHour().withMaximumValue().
                secondOfMinute().withMaximumValue().
                millisOfSecond().withMaximumValue().
                toString(DateConstants.YYYY_MM_DD_HH_MM_SS);
        log.info("今天最晚的结束时间：" + fullDateTimeStr);
        return fullDateTimeStr;
    }

    /**
     * 获取昨天的开始的全量时间 YYYY_MM_DD_HH_MM_SS
     */
    public static String getStartFullTimeOfYesterday() {
        String fullDateTimeStr = new LocalDateTime().
                plusDays(-1).
                hourOfDay().withMaximumValue().
                minuteOfHour().withMinimumValue().
                secondOfMinute().withMinimumValue().
                millisOfSecond().withMinimumValue().
                toString(DateConstants.YYYY_MM_DD_HH_MM_SS);
        log.info("昨天最早的开始时间：" + fullDateTimeStr);
        return fullDateTimeStr;
    }

    /**
     * 获取月初的开始的全量时间 YYYY_MM_DD_HH_MM_SS
     */
    public static String getStartFullTimeOfMonth() {
        String fullDateTimeStr = new LocalDateTime().
                dayOfMonth().withMinimumValue().
                hourOfDay().withMaximumValue().
                minuteOfHour().withMinimumValue().
                secondOfMinute().withMinimumValue().
                millisOfSecond().withMinimumValue().
                toString(DateConstants.YYYY_MM_DD_HH_MM_SS);
        log.info("月初最早的开始时间：" + fullDateTimeStr);
        return fullDateTimeStr;
    }

    /**
     * 获取指定时间的最晚的全量时间 YYYY_MM_DD_HH_MM_SS
     */
    public static String getEndFullTimeByDateStr(String dataStr) {
        Date date = getDateByDateStr(dataStr);
        String fullDateTimeStr = new LocalDateTime(date).
                hourOfDay().withMaximumValue().
                minuteOfHour().withMaximumValue().
                secondOfMinute().withMaximumValue().
                millisOfSecond().withMaximumValue().
                toString(DateConstants.YYYY_MM_DD_HH_MM_SS);
        log.info("指定的时间最晚结束时间：" + fullDateTimeStr);
        return fullDateTimeStr;
    }

    /**
     * 转化date为LocalDateTime，并获取最早开始时间 YYYY_MM_DD_HH_MM_SS
     */
    public static LocalDateTime getStartLocalTimeByDate(Date date) {
        LocalDateTime localDateTime = new LocalDateTime(date).
                hourOfDay().withMaximumValue().
                minuteOfHour().withMaximumValue().
                secondOfMinute().withMaximumValue().
                millisOfSecond().withMaximumValue();
        log.info("转化date为LocalDateTime，并获取最早开始时间：" + localDateTime.toString(DateConstants.YYYY_MM_DD_HH_MM_SS));
        return localDateTime;
    }

    /**
     * 距离指定时间点的时间间隔（单位：天）
     */
    public static long getDayGapFromDate(String dateStr, Date date) {
        Date dateByDateString = getDateByDateStr(dateStr);
        LocalDateTime dateTimeAgo = getStartLocalTimeByDate(dateByDateString);
        LocalDateTime currentDateTime = getStartLocalTimeByDate(date);

        int days = Days.daysBetween(dateTimeAgo, currentDateTime).getDays();
        log.info("距离指定时间点的时间间隔（单位：天）：" + days);
        return days;
    }

    /**
     * 距离指定时间点的时间间隔（单位：天）
     */
    public static long getDayGapFromDate(String dateStr1, String dateStr2) {
        Date date1 = getDateByDateStr(dateStr1);
        LocalDateTime dateTime1 = getStartLocalTimeByDate(date1);

        Date date2 = getDateByDateStr(dateStr2);
        LocalDateTime dateTime2 = getStartLocalTimeByDate(date2);

        int days = Days.daysBetween(dateTime1, dateTime2).getDays();
        log.info("距离指定时间点的时间间隔（单位：天）：" + days);
        return days;
    }

    /**
     * 最小的时间字符
     */
    public static String getSmallerDateStr(String dateStr1, String dateStr2) {
        long compareValue = getDayGapFromDate(dateStr1, dateStr2);
        String smallerStr = compareValue >= 0 ? dateStr1 : dateStr2;
        log.info("最小的时间字符：" + smallerStr);
        return smallerStr;
    }

    /**
     * 是否在同一天
     */
    public static boolean whetherInSameDay(String dateStr1, String dateStr2) {
        boolean sameDay = getDayGapFromDate(dateStr1, dateStr2) == 0;
        log.info("是否在同一天：" + sameDay);
        return sameDay;
    }

}
